<template>
  <div ref="threeContainer" class="three-container"></div>
</template>

<script>
import * as THREE from 'three';
import { onMounted, ref } from 'vue';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

export default {
  name: 'SnowScene',
  setup() {
    const threeContainer = ref(null);

    onMounted(() => {
      initThree();
    });

    const initThree = () => {
      // 创建场景
      const scene = new THREE.Scene();

      // 创建相机
      const camera = new THREE.PerspectiveCamera(75, threeContainer.value.clientWidth / threeContainer.value.clientHeight, 0.1, 1000);
      camera.position.z = 15;

      // 创建渲染器
      const renderer = new THREE.WebGLRenderer();
      renderer.setSize(threeContainer.value.clientWidth, threeContainer.value.clientHeight);
      threeContainer.value.appendChild(renderer.domElement);

      // 添加环境光
      const ambientLight = new THREE.AmbientLight(0x404040);
      scene.add(ambientLight);

      // 添加点光源
      const pointLight = new THREE.PointLight(0xffffff, 1);
      pointLight.position.set(5, 5, 5);
      scene.add(pointLight);

      // 添加地面
      const planeGeometry = new THREE.PlaneGeometry(100, 100);
      const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 });
      const plane = new THREE.Mesh(planeGeometry, planeMaterial);
      plane.rotation.x = -Math.PI / 2;
      scene.add(plane);

      // 添加背景
      const skyboxGeometry = new THREE.BoxGeometry(1000, 1000, 1000);
      const skyboxMaterial = new THREE.MeshBasicMaterial({
        map: new THREE.TextureLoader().load('/models/skybox.jpg'),
        side: THREE.BackSide,
      });
      const skybox = new THREE.Mesh(skyboxGeometry, skyboxMaterial);
      scene.add(skybox);

      // 创建雪花粒子
      const snowGeometry = new THREE.BufferGeometry();
      const snowVertices = [];

      for (let i = 0; i < 10000; i++) {
        const x = Math.random() * 200 - 100;
        const y = Math.random() * 100;
        const z = Math.random() * 200 - 100;

        snowVertices.push(x, y, z);
      }

      snowGeometry.setAttribute('position', new THREE.Float32BufferAttribute(snowVertices, 3));

      const snowMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 0.1 });
      const snow = new THREE.Points(snowGeometry, snowMaterial);
      scene.add(snow);

      // 添加相机控制器
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.update();

      // 渲染循环
      const animate = function () {
        requestAnimationFrame(animate);

        // 使雪花下落
        snowGeometry.attributes.position.array.forEach((v, i) => {
          if (i % 3 === 1) {
            snowGeometry.attributes.position.array[i] -= 0.05;
            if (snowGeometry.attributes.position.array[i] < 0) {
              snowGeometry.attributes.position.array[i] = 100;
            }
          }
        });

        snowGeometry.attributes.position.needsUpdate = true;

        controls.update();
        renderer.render(scene, camera);
      };

      animate();

      // 监听窗口大小变化
      window.addEventListener('resize', () => {
        camera.aspect = threeContainer.value.clientWidth / threeContainer.value.clientHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(threeContainer.value.clientWidth, threeContainer.value.clientHeight);
      });
    };

    return {
      threeContainer,
    };
  },
};
</script>

<style scoped>
.three-container {
  width: 100%;
  height: 100%;
}
</style>